/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package com.googlecode.ivybeans.module.classpath;

import com.googlecode.ivybeans.facade.ArtifactInfo;
import com.googlecode.ivybeans.facade.ResolvedIvyLibrary;
import com.googlecode.ivybeans.module.IvyLibraryController;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.netbeans.api.project.FileOwnerQuery;
import org.netbeans.api.project.Project;
import org.netbeans.spi.java.classpath.ClassPathImplementation;
import org.netbeans.spi.java.classpath.PathResourceImplementation;
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileStateInvalidException;
import org.openide.filesystems.FileUtil;
import org.openide.util.Exceptions;

/**
 * 
 * @author lforet
 */
public final class ScopedClassPathImpl implements ClassPathImplementation, PropertyChangeListener {

    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
    private IvyLibraryController ivyLibraryController;
    private final Project project;
    private final ClassPathScope scope;

    ScopedClassPathImpl(Project project, ClassPathScope scope) {
        this.project = project;
        this.scope = scope;
        ivyLibraryController = project.getLookup().lookup(IvyLibraryController.class);
        ivyLibraryController.addPropertyChangeListener(this);
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        pcs.addPropertyChangeListener(listener);
    }

    public List<? extends PathResourceImplementation> getResources() {
        List<PathResourceImplementation> result = new ArrayList<PathResourceImplementation>();
        for (File file : getIvyArtifacts()) {
            try {
                FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(file));
                FileOwnerQuery.markExternalOwner(fo, project, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
                URL archUrl = FileUtil.getArchiveRoot(fo).getURL();
                result.add(ClassPathSupport.createResource(archUrl));
            } catch (FileStateInvalidException ex) {
                Exceptions.printStackTrace(ex);
            }
        }
        return result;
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        pcs.removePropertyChangeListener(listener);
    }

    public void propertyChange(PropertyChangeEvent evt) {
        if (IvyLibraryController.IVY_LIBRARY_RESOLVED.equals(evt.getPropertyName())) {
            pcs.firePropertyChange(ClassPathImplementation.PROP_RESOURCES, null, null);
        }
    }

    private List<File> getIvyArtifacts() {
        List<File> artifacts = new ArrayList<File>();
        ResolvedIvyLibrary resolvedIvyLibrary = ivyLibraryController.getResolvedLibrary(scope);
        if (resolvedIvyLibrary != null) {
            Collection<ArtifactInfo> artifactInfos = resolvedIvyLibrary.getArtifacts();
            for (ArtifactInfo artifactInfo : artifactInfos) {
                if (artifactInfo.hasJar()) artifacts.add(artifactInfo.getJarFile());
                if (artifactInfo.hasSource()) artifacts.add(artifactInfo.getSourceFile());
//                if (artifactInfo.hasJavadoc()) artifacts.add(artifactInfo.getJavadocFile());
            }
        }
        return artifacts;
    }
}
